
public class GameOfLife {

	EvolvedPopulation population;
	RuleSet rules;
	int neighborhoodSize;
	
	GameOfLife ()
	{
	}
	
	GameOfLife (EvolvedPopulation pop, RuleSet ruleSet, int neighborhood)
	{
		init(pop,ruleSet, neighborhood);
	}
	
	private void init(EvolvedPopulation pop, RuleSet ruleSet, int neighborhood)
	{
		neighborhoodSize = neighborhood;
		population = pop;
		rules = ruleSet;
	}
	
	public void reset(EvolvedPopulation pop, RuleSet ruleSet, int radius) { init(pop,ruleSet, radius);}
	
	
	public void runSimulation(int generations)
	{
		int[][] biggerArray = generateBigArray();
		
		int xSize = population.getXSize();
		int ySize = population.getYSize();
		KeyGenerator generator = new KeyGenerator();
		
		for (int generation=0; generation<generations; generation++)
		{
			for(int i=0; i<xSize-1; i++ )
			{
				for(int j=0;j<ySize-1;j++)
				{
					for(int k=neighborhoodSize;k>0;k--)
					{
						//left
						generator.addDigit(biggerArray[(i+neighborhoodSize)-k][j+neighborhoodSize]);
						//above
						generator.addDigit(biggerArray[(i+neighborhoodSize)][(j+neighborhoodSize)+k]);
						//right
						generator.addDigit(biggerArray[(i+neighborhoodSize)+k][j+neighborhoodSize]);
						//below
						generator.addDigit(biggerArray[(i+neighborhoodSize)][(j+neighborhoodSize)-k]);	
					}
					//center
					generator.addDigit(biggerArray[(i+neighborhoodSize)][j+neighborhoodSize]);
					
					population.set(i, j,
							rules.ruleAnswer(generator.getKey()));
					generator.reset();
				}
			}
			population.swapPopulations();
			biggerArray = generateBigArray();
		}
	}
	
	private int formKey(int p1, int p2, int p3, int p4, int p5)
	{
		int ret = (p1*10000) + (p2*1000) + (p3*100) + (p4*10) + p5;
		return ret;
	}
	
	
	
	private int[][] generateBigArray()
	{
		int xSize = population.getXSize();
		int ySize = population.getYSize();
		int[][] currentPopulation = population.getCurrenPopulation();
		
		int[][] biggerArray;
		biggerArray = new int[xSize + (2*neighborhoodSize)][ySize + (2*neighborhoodSize)];
		for(int i=0; i<(xSize);i++)
		{
			//Copy from the current population to the middle of the larger array
			//next step will be to copy the last two rows and columns over again
			System.arraycopy(currentPopulation[i], 0, biggerArray[i+neighborhoodSize], neighborhoodSize, currentPopulation[i].length);
		}
		//Now copy the last neighborhood size j columns into the first two.
		for(int i=neighborhoodSize,j=0;i>0;i--,j++)
		{
			System.arraycopy(currentPopulation[(xSize-1)-j], 0, biggerArray[i], neighborhoodSize, currentPopulation[(xSize-1)-j].length);
			System.arraycopy(currentPopulation[j], 0, biggerArray[(xSize)+neighborhoodSize+j], neighborhoodSize, 
					currentPopulation[(xSize-1)-j].length);
		}
		//No copy the top2 to the bottom two and vice versa
		for(int i=0;i<xSize;i++)
		{
			for(int k=0;k<neighborhoodSize;k++)
			{
				biggerArray[i+neighborhoodSize][(neighborhoodSize-1)-k] = currentPopulation[i][(xSize-1)-k];
				biggerArray[i+neighborhoodSize][(ySize) + neighborhoodSize+k] = currentPopulation[i][k];
			}
		}
		return biggerArray;
	}
}
